package solution.s_1002;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 解题思路：
 *      首先针对传入的字符串列表，分别统计每个字符串每个字符出现的次数。
 *      比如对于字符串“bella”，最后统计的结果便是{b:1,e:1,l:2,a:1}
 *      会统计出一个 Map<Character, Integer> 列表。
 *      然后对 Map 列表做求交集操作（其实这儿只是类似求交集操作，当两个 map 有相同 key，value 取小的那个）。
 *      最后对最终的 Map 按照数量，输出到一个 List 中返回。
 */
public class Solution20201014 {
    public List<String> commonChars(String[] A) {
        if (A.length == 1) {
            return Arrays.asList(A[0].split(""));
        }

        List<Map<String, Long>> characterCountList = new ArrayList<>(A.length);

        for (String a : A) {
            Map<String, Long> characterCount = Arrays.stream(a.split(""))
                    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
            characterCountList.add(characterCount);
        }

        Map<String, Long> resultMap = mergeMap(characterCountList.get(0), characterCountList.get(1));
        for (int i = 2; i < characterCountList.size(); i ++) {
            resultMap = mergeMap(resultMap, characterCountList.get(i));
        }

        List<String> result = new ArrayList<>();
        resultMap.forEach((k, v) -> {
            for (int i = 0; i < v; i ++) {
                result.add(k);
            }
        });

        return result;
    }

    private Map<String, Long> mergeMap(Map<String, Long> map1, Map<String, Long> map2) {
        Map<String, Long> result = new HashMap<>();

        // key 交集
        Set<String> keySet = map1.keySet();
        keySet.retainAll(map2.keySet());

        // 取比较小的值
        for (String s : keySet) {
            result.put(s, Math.min(map1.get(s), map2.get(s)));
        }

        return result;
    }
}
